function costs = cmaesParallelSplitRough(gainsPop)
    global rtp InitialGuess

    %allocate costs vector and paramsets the generation
    popSize = size(gainsPop,2);

    numTerrains = 5;
    rampSlope = 0.0025;
    [groundX, groundZ, groundTheta] = generateGround('flat');

    costs = nan(popSize*numTerrains,1);
    paramSets = cell(popSize*numTerrains,1);

    %create param sets
    gainind = 1;
    for i = 1:numTerrains:(numTerrains*popSize)
        %set gains
        Gains = InitialGuess.*exp(gainsPop(:,gainind));
        paramSets{i} = Simulink.BlockDiagram.modifyTunableParameters(rtp, ...
            'GainGAS',               Gains( 1), ...
            'GainGLU',               Gains( 2), ...
            'GainHAM',               Gains( 3), ...
            'GainKneeOverExt',       Gains( 4), ...
            'GainSOL',               Gains( 5), ...
            'GainSOLTA',             Gains( 6), ...
            'GainTA',                Gains( 7), ...
            'GainVAS',               Gains( 8), ...
            'Kglu',                  Gains( 9), ...
            'PosGainGG',             Gains(10), ...
            'SpeedGainGG',           Gains(11), ...
            'hipDGain',              Gains(12), ...
            'hipPGain',              Gains(13), ...
            'kneeExtendGain',        Gains(14), ...
            'kneeFlexGain',          Gains(15), ...
            'kneeHoldGain1',         Gains(16), ...
            'kneeHoldGain2',         Gains(17), ...
            'kneeStopGain',          Gains(18), ...
            'legAngleFilter',        Gains(19), ...
            'legLengthClr',          Gains(20), ...
            'simbiconGainD',         Gains(21), ...
            'simbiconGainV',         Gains(22), ...
            'simbiconLegAngle0',     Gains(23));

        %set ground heights
        for j = 0:(numTerrains-1)
            rng('default');
            rng(4*j);
            for k = 21:2:length(groundX)
                groundZ(k) = groundZ(k-2) + ...
                    groundX(k-19)*2*(rand - 0.5)*rampSlope;
                groundZ(k+1) = groundZ(k);
            end
            groundTheta = [atan(diff(groundZ)./diff(groundX)), 0];
    
            paramSets{i+j} = ...
                Simulink.BlockDiagram.modifyTunableParameters(paramSets{i}, ...
                'groundZ',     groundZ, ...
                'groundTheta', groundTheta);
        end
        gainind = gainind + 1;
    end
    rng('shuffle');

    %simulate each sample and store cost
    parfor i = 1:length(paramSets)
        costs(i) = evaluateCostParallel(paramSets{i})
    end

    %calculate median across terrains
    costs = reshape(costs,numTerrains,popSize)
    isinvalid = sum(isnan(costs))>1;
    costs = nanmean(costs);
    costs(isinvalid) = nan
